import src.SNMP.Mulit as mul
import src.SNMP.Node as nod
import src.SNMP.Master as mas
from src import WR_config,Device_config
from src import cycle_calc
from epics import caget,caput
from src import Master_raw_data,Mulit_raw_data,Node_raw_data
import time
from multiprocessing import Pool
from src import trigger_close,trigger_single,trigger_coiled,Bypass
from src import Master_ip_data
from src import check_ping

def IOC_init(Driver):
    impWavePatternTable = nod.impWavePatternTable()
    for pvname,host in Node_raw_data.items():
        if check_ping(host):
            try:
                MC0_data = impWavePatternTable.walk_impWaveTableMC0(host)
                delay = int(list(MC0_data.values())[0])/250
                width = int(list(MC0_data.values())[16])/250
                # Queue.balancer.send_message({"from":"System","pvname":Device_config["延时"].format(pvname),"opr":"write","value":delay})
                # Queue.balancer.send_message({"from":"System","pvname":Device_config["脉宽"].format(pvname),"opr":"write","value":width})
                Driver.setParam(Device_config["延时"].format(pvname),delay)
                Driver.setParam(Device_config["脉宽"].format(pvname),width)
                Driver.updatePV(Device_config["延时"].format(pvname))
                Driver.updatePV(Device_config["脉宽"].format(pvname))
                # a = caput(Device_config["延时"].format(pvname),delay)
                # a = caput(Device_config["脉宽"].format(pvname),width)
            except:
                print(f"ip:\t{host} IOC数据初始化失败")
                print(impWavePatternTable.walk_impWaveTableMC0(host))
                continue
        else:
            # print(f"ip:\t{host} IOC数据初始化失败")
            continue
        
    

def init(host,type):
    print(f"ip:{host} 开始初始化,")
    try:
        if type == "Mulit" or type == "Master":
            if type == "Mulit":
                impCtrlApply = mul.impCtrlApply()
                impPolarityConfig = mul.impPolarityConfig()
                impWavePatternConfig = mul.impWavePatternConfig()
            elif type == "Master":
                impCtrlApply = mas.impCtrlApply()
                impPolarityConfig = mas.impPolarityConfig()
                impWavePatternConfig = mas.impWavePatternConfig()
            # # 网络参数配置
            # impNetAddrConfig = mul.impNetAddrConfig()
            # # PC
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["PC"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,21)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["PC"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,22)
            # # M1
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["M1"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,23)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["M1"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,24)
            # # M2
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["M2"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,25)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["M2"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,26)
            
            # 配置输出极性
            impPolarityConfig.set_PolarityMC0(host,0)
            impPolarityConfig.set_PolarityMC1(host,0)
            impPolarityConfig.set_PolarityMC2(host,0)
            impPolarityConfig.set_PolarityMC3(host,0)
            impPolarityConfig.set_PolarityMC4(host,0)
            impPolarityConfig.set_PolarityMC5(host,0)
            impPolarityConfig.set_PolarityMC6(host,0)
            impPolarityConfig.set_PolarityMC7(host,0)
            impPolarityConfig.set_PolarityMC8(host,0)
            impPolarityConfig.set_PolarityMC9(host,0)
            # 应用极性
            impCtrlApply.set_impCtrlApply(host,13)
            # 配置输出事例
            impWavePatternConfig.set_WavePatternIndexMC0(host,0)
            impWavePatternConfig.set_WavePatternIndexMC1(host,1)
            impWavePatternConfig.set_WavePatternIndexMC2(host,2)
            impWavePatternConfig.set_WavePatternIndexMC3(host,3)
            impWavePatternConfig.set_WavePatternIndexMC4(host,4)
            impWavePatternConfig.set_WavePatternIndexMC5(host,5)
            impWavePatternConfig.set_WavePatternIndexMC6(host,6)
            impWavePatternConfig.set_WavePatternIndexMC7(host,7)
            impWavePatternConfig.set_WavePatternIndexMC8(host,8)
            impWavePatternConfig.set_WavePatternIndexMC9(host,9)
            # 应用事例
            impCtrlApply.set_impCtrlApply(host,14)
            # 写入Flash
            impCtrlApply.set_impCtrlApply(host,3)
        elif type == "Node":
            impCtrlApply = nod.impCtrlApply()
            # # 网络参数配置
            # impNetAddrConfig = nod.impNetAddrConfig()
            # # PC
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["PC"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,21)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["PC"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,22)
            # # M1
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["M1"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,23)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["M1"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,24)
            # # M2
            # impNetAddrConfig.set_impWriteIP(host,NetAddrConfig["M2"]["ip"])
            # impCtrlApply.set_impCtrlApply(host,25)
            # impNetAddrConfig.set_impWriteMAC(host,NetAddrConfig["M2"]["mac"])
            # impCtrlApply.set_impCtrlApply(host,26)

            # 配置输出极性
            impPolarityConfig = nod.impPolarityConfig()
            impPolarityConfig.set_PolarityMC0(host,0)
            impPolarityConfig.set_PolarityMC1(host,1)
            # 应用极性
            impCtrlApply.set_impCtrlApply(host,13)
            # 配置输出事例
            impPolarityConfig = nod.impWavePatternConfig()
            impPolarityConfig.set_WavePatternIndexMC0(host,0)
            impPolarityConfig.set_WavePatternIndexMC1(host,1)
            # 应用事例
            impCtrlApply.set_impCtrlApply(host,14)
            # 写入Flash
            impCtrlApply.set_impCtrlApply(host,3)
    except Exception as e:
        print(f"ip:{host} 初始化失败,错误信息为:{e}")
def Wave_set(host,type,delay,width,MC):
    try:
        FREQ = caget(WR_config["频率设定"])
        _100ms_num, _4ns_num = cycle_calc(FREQ,width,delay)
        if type == "Mulit":
            impCtrlApply = mul.impCtrlApply()
            impWavePatternSetGroup = mul.impWavePatternSetGroup()
        elif type == "Master":
            impCtrlApply = mas.impCtrlApply()
            impWavePatternSetGroup = mas.impWavePatternSetGroup()
        elif type == "Node":
            impCtrlApply = nod.impCtrlApply()
            impWavePatternSetGroup = nod.impWavePatternSetGroup()
        try:
            impWavePatternSetGroup.set_impWavePatternIndex(host,0)
            impWavePatternSetGroup.set_impWavePatternMC(host,MC)
            impWavePatternSetGroup.set_impWavePatternDelay(host,delay)
            impWavePatternSetGroup.set_impWavePatternWidth(host,width)
            impWavePatternSetGroup.set_impWavePatternIdle4ns(host,_4ns_num)
            impWavePatternSetGroup.set_impWavePatternIdle100ms(host,_100ms_num)
            impWavePatternSetGroup.set_impWavePatternSet(host,1)
            impCtrlApply.set_impCtrlApply(host,3)
            print(f"host:{host}\tMC:{MC}\t设置参数为:\n延时:{delay}\t宽度:{width}\t100ms:{_100ms_num}\t4ns:{_4ns_num}")
        except Exception as e:
            print(f"ip:{host} 输出波形设置失败,错误信息为:{e}")
    except Exception as e:
        print(f"ip:{host} 获取频率失败,错误信息为:{e}")
    
    
def Delay(host,type,value:int = None,MC:int = None):
    try:
        if not value == None:
            delay = int(value) * 250
            if type == "Mulit":
                impWavePatternTable = mul.impWavePatternTable()
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                width = int(list(Table0.values())[MC+10])
            if type == "Master":
                impWavePatternTable = mas.impWavePatternTable()
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                width = int(list(Table0.values())[MC+10])
            elif type == "Node":
                impWavePatternTable = nod.impWavePatternTable()
                MC0_data = impWavePatternTable.walk_impWaveTableMC0(host)
                width = int(list(MC0_data.values())[16])
        Wave_set(host,type,delay,width,MC)
    except Exception as e:
        print(f"ip:{host} 输出波形延时设置失败,错误信息为:{e}")
    

def Width(host,type,value:int = None,MC:int = None):
    try:
        if not value == None:
            width = int(value) * 250
            if type == "Mulit":
                impWavePatternTable = mul.impWavePatternTable()
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                delay = int(list(Table0.values())[MC+0])
            if type == "Master":
                impWavePatternTable = mas.impWavePatternTable()
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                delay = int(list(Table0.values())[MC+0])
            elif type == "Node":
                impWavePatternTable = nod.impWavePatternTable()
                MC0_data = impWavePatternTable.walk_impWaveTableMC0(host)
                delay = int(list(MC0_data.values())[0])

        Wave_set(host,type,delay,width,MC)
    except Exception as e:
        print(f"ip:{host} 输出波形脉宽设置失败,错误信息为:{e}")

# def enable(host,type,enable,MC:int = 0):
#     try:
#         if type == "Mulit" or type == "Master":
#             if type == "Mulit":
#                 impCtrlApply = mul.impCtrlApply()
#                 impCtrlMENA = mul.impCtrlMENA()
#             elif type == "Master":
#                 impCtrlApply = mas.impCtrlApply()
#                 impCtrlMENA = mas.impCtrlMENA()
            
#             if MC == 0:
#                 impCtrlMENA.set_impCtrlMC0Ena(host,enable)
#             elif MC == 1:
#                 impCtrlMENA.set_impCtrlMC1Ena(host,enable)
#             elif MC == 2:
#                 impCtrlMENA.set_impCtrlMC2Ena(host,enable)
#             elif MC == 3:
#                 impCtrlMENA.set_impCtrlMC3Ena(host,enable)
#             elif MC == 4:
#                 impCtrlMENA.set_impCtrlMC4Ena(host,enable)
#             elif MC == 5:
#                 impCtrlMENA.set_impCtrlMC5Ena(host,enable)
#             elif MC == 6:
#                 impCtrlMENA.set_impCtrlMC6Ena(host,enable)
#             elif MC == 7:
#                 impCtrlMENA.set_impCtrlMC7Ena(host,enable)
#             elif MC == 8:
#                 impCtrlMENA.set_impCtrlMC8Ena(host,enable)
#             elif MC == 9:
#                 impCtrlMENA.set_impCtrlMC9Ena(host,enable)
#                 # 应用使能参数
#             impCtrlApply.set_impCtrlApply(host,11)
#             # 写入Flash
#             impCtrlApply.set_impCtrlApply(host,3)

#         elif type == "Node":
#             impCtrlApply = nod.impCtrlApply()
#             impCtrlMENA = nod.impCtrlMENA()
#             impCtrlMENA.set_impCtrlMC0Ena(host,enable)
#             # 应用使能参数
#             impCtrlApply.set_impCtrlApply(host,11)
#             # 写入Flash
#             impCtrlApply.set_impCtrlApply(host,3)
#     except Exception as e:
#         print(f"ip:{host} 输出波形使能设置失败,错误信息为:{e}")
def FREQ_Thread_set(host,type):
    try:
        if type == "Mulit" or type == "Master":
            if type == "Mulit":
                impWavePatternTable = mul.impWavePatternTable()
                MC = 0
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 1
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 2
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 3
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 4
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 5
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 6
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 7
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 8
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 9
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
            elif type == "Master":
                impWavePatternTable = mas.impWavePatternTable()
                MC = 0
                Table0 = impWavePatternTable.walk_impWavePatternTable0(host)
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 1
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 2
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 3
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 4
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 5
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 6
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 7
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 8
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
                MC = 9
                delay = int(list(Table0.values())[MC+0])
                width = int(list(Table0.values())[MC+10])
                Wave_set(host,type,delay,width,MC)
        elif type == "Node":
            impWavePatternTable = nod.impWavePatternTable()
            MC0_data = impWavePatternTable.walk_impWaveTableMC0(host)
            MC = 0
            delay = int(list(MC0_data.values())[0])
            width = int(list(MC0_data.values())[16])
            Wave_set(host,type,delay,width,MC)
    except Exception as e:
        print(f"ip:{host} 频率设置失败,错误信息为:{e}")


def FREQ_Set():
    # pool = Pool(processes=8)
    FREQ_State = caput(WR_config["频率设定状态"],0)
    pool = Pool(processes=int(round((len(Master_raw_data)+len(Node_raw_data))/3,0))+len(Mulit_raw_data))
    start_time = time.time()
    for value in Master_raw_data.values():
        host = value["host"]
        type = "Master"
        pool.apply_async(FREQ_Thread_set, args=(host,type,))
    for value in Mulit_raw_data.values():
        host = value["host"]
        type = "Mulit"
        pool.apply_async(FREQ_Thread_set, args=(host,type,))

    for host in Node_raw_data.values():
        type = "Node"
        pool.apply_async(FREQ_Thread_set, args=(host,type,))   
    pool.close()
    pool.join()
    print("频率设定完成,用时:",time.time()-start_time,"s")
    FREQ_State = caput(WR_config["频率设定状态"],1)
    impBPSConfig = mas.impBPSConfig()
    status1 = impBPSConfig.get_impCtrlTrigger(Master_ip_data["M1 ip"])["impCtrlTrigger"]
    status2 = impBPSConfig.get_impCtrlTrigger(Master_ip_data["M2 ip"])["impCtrlTrigger"]
    if status1 == "11" and status2 == "11":
        trigger(1)

def trigger(value):
    impBPSConfig = mas.impBPSConfig()
    if value == 0:
        trigger_close()
    elif value == 1:
        trigger_coiled()
    elif value == 2:
        trigger_single()
    status_value=0
    for i in range(10):
        time.sleep(0.1)
        try:
            status1 = impBPSConfig.get_impCtrlTrigger(Master_ip_data["M1 ip"])["impCtrlTrigger"]
            status2 = impBPSConfig.get_impCtrlTrigger(Master_ip_data["M2 ip"])["impCtrlTrigger"]
            if ((status1 =="1" and value==0) or (status1=="11" and value==1) or (status1=="10" and value==2)) and \
                ((status2 =="1" and value==0) or (status2=="11" and value==1) or (status2=="10" and value==2)):
                status_value=1
                break
        except Exception as e:
            print(f"触发状态回读失败,错误信息为:{e}")
    Trigger_State = caput(WR_config["触发状态"],status_value)
    print("触发状态:",status_value)

def reset():
    impCtrlApply = mas.impCtrlApply()
    try:
        impCtrlApply.set_impCtrlApply(Master_ip_data["M1 ip"],value=31)
        impCtrlApply.set_impCtrlApply(Master_ip_data["M2 ip"],value=31)
    except Exception as e:
        print(f"复位Overtime失败,错误信息为:{e}")


# def Heartbeat_Enable(host,type,enable,MC:int = 0):
#     try:
#         if type == "Mulit" or type == "Master":
#             if type == "Mulit":
#                 impCtrlApply = mul.impCtrlApply()
#                 impCtrlMENA = mul.impCtrlMENA()
#             elif type == "Master":
#                 impCtrlApply = mas.impCtrlApply()
#                 impCtrlMENA = mas.impCtrlMENA()
            
#             if MC == 0:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 1:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 2:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 3:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 4:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 5:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 6:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 7:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 8:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             elif MC == 9:
#                 impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#                 # 应用使能参数
#             impCtrlApply.set_impCtrlApply(host,11)
#             # 写入Flash
#             impCtrlApply.set_impCtrlApply(host,3)

#         elif type == "Node":
#             impCtrlApply = nod.impCtrlApply()
#             impCtrlMENA = nod.impCtrlMENA()
#             impCtrlMENA.set_impCtrlHeartbeatEna(host,enable)
#             # 应用使能参数
#             impCtrlApply.set_impCtrlApply(host,11)
#             # 写入Flash
#             impCtrlApply.set_impCtrlApply(host,3)
#     except Exception as e:
#         print(f"ip:{host} 输出波形使能设置失败,错误信息为:{e}")

def Opr_Bypass(host,type,value):
    try:
        if type == "Node":
            impCtrlDeviceNum = int(nod.impBPSConfig().get_impCtrlDeviceNum(ip=host)["impCtrlDeviceNum"])
    except Exception as e:
        print(f"ip:{host} Bypass Device  Num 获取失败,错误信息为:{e}")
    Bypass(impCtrlDeviceNum,value)
